function askapLivePage(options) {
  // get the text for the page first
  this.getPageText();

  // make the Google Map area
  this.googleMapGetCentre();
}

askapLivePage.prototype.splitResponse = function(data) {
  var infoArray = [];

  var antennaArray = data.split(/\n/);
  for (var i = 0; i < antennaArray.length; i++) {
    if (/\|/.test(antennaArray[i])) {
      infoArray[i] = antennaArray[i].split(/[\|]/);
    } else {
      infoArray[i] = antennaArray[i].split(/[\s]/);
    }
  }

  return infoArray;
};

askapLivePage.prototype.googleMapInit = function() {

  // the antenna that the user has selected
  this.currentAntSelection = null;

  // the next and previous links
  this.navigationNext = null;
  this.navigationPrev = null;

  // get the map centre coordinate
  this.googleMapGetCentre();
};

askapLivePage.prototype.googleMapGetCentre = function() {
  this.dbQuery({
    content: {
      action: 'coordinates', antenna: '1'
    },
    functionCall: 'googleMapMake'
  });
};

askapLivePage.prototype.googleMapMake = function(data, ioargs) {
  var centreCoord = this.splitResponse(data);
  var latLng = new google.maps.LatLng(centreCoord[0][1],
    centreCoord[0][2]);

  var myOptions = {
    zoom: 13, center: latLng,
    mapTypeControl: false,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  };

  this.askapMap = new google.maps.Map(dojo.byId('map_canvas'), myOptions);

  this.googleMapStateDetails();
};

askapLivePage.prototype.googleMapStateDetails = function() {

  // get all the state information
  this.dbQuery({
    content: {
      action: 'state_table', antenna: 'all'
    },
    functionCall: 'googleMapStates'
  });
};

askapLivePage.prototype.googleMapStates = function(data, ioargs) {
  this.stateInfo = this.splitResponse(data);

  this.googleMapAntDetails();
};

askapLivePage.prototype.googleMapAntDetails = function() {

  // get all the antenna information
  this.dbQuery({
    content: {
      action: 'live_info', antenna: 'all'
    },
    functionCall: 'googleMapAnts'
  });
};

askapLivePage.prototype.googleMapAnts = function(data, ioargs) {
  this.antennaInfo = this.splitResponse(data);
  // find out some information about the antennas we have
  this.minAntNumber = 0;
  this.maxAntNumber = 0;
  for (var i = 0; i < this.antennaInfo.length; i++) {
    var tNum = this.antennaInfo[i][0];
    if (!tNum) {
      this.antennaInfo.splice(i, 1);
      i--;
      continue;
    }
    tNum = parseInt(tNum);
    if (i == 0) {
      this.minAntNumber = this.maxAntNumber = tNum;
    } else {
      this.minAntNumber = (tNum < this.minAntNumber) ? tNum :
	this.minAntNumber;
      this.maxAntNumber = (tNum > this.maxAntNumber) ? tNum :
	this.maxAntNumber;
    }
  }

  this.googleMapLoadIcons();

  // pick a random antenna to begin on
  var randAntenna = Math.floor(Math.random() * this.antennaInfo.length);

  // add the markers to the map
  for (var i = 0; i < this.antennaInfo.length; i++) {
    // get the antenna position
    var antennaLatLng = new google.maps.LatLng(this.antennaInfo[i][1],
      this.antennaInfo[i][2]);

    // the state of the antenna
    var antennaStateNum = -1;
    for (var j = 0; j < this.stateInfo.length; j++) {
      if (this.stateInfo[j][3] == this.antennaInfo[i][7]) {
	antennaStateNum = j;
      }
    }

    // if the antenna has no name, we give it a generic one
    if (this.antennaInfo[i][5] == '') {
      this.antennaInfo[i][5] = 'unnamed';
    }

    // get the antenna state colour
    var antIconColour = this.googleMapAntColour(antennaStateNum);

    // make the antenna marker
    var antennaMarker = new google.maps.Marker({
      position: antennaLatLng,
      map: this.askapMap,
      icon: this.icons[antIconColour].small,
      shadow: this.icons.shadow.small,
      shape: this.iconShape,
      antNum: i,
      antState: antennaStateNum,
      colour: antIconColour
    });
    if (i == randAntenna) {
      this.googleMapShowDetails(antennaMarker);
    }
    this.antennaInfo[i][8] = antennaMarker;

    // make the antenna marker do something when the user clicks it
    google.maps.event.addListener(antennaMarker, 'click',
      dojo.hitch(this, 'googleMapShowDetails', antennaMarker));
  }

  this.googleMapAddLegend();

};

askapLivePage.prototype.googleMapAddLegend = function() {

  // add a legend to the map
  this.colourLegend = dojo.create('div', {
    'class': 'legend' });

  // one entry for each icon colour
  for (var i = 0; i < this.iconColours.length; i++) {
    if (i > 0) {
      // clear the float
      var clearDiv = dojo.create('div', {
	'class': 'legendclear' });
      this.colourLegend.appendChild(clearDiv);
    }
    // the icon image
    var legendImage = dojo.create('div', {
      'class': 'legendImage' });
    var lImg = dojo.create('img', {
      'src': this.iconFiles[i] });
    legendImage.appendChild(lImg);
    this.colourLegend.appendChild(legendImage);

    // the description
    var legendEntry = dojo.create('div', {
      'class': 'legend' + this.iconColours[i],
      innerHTML: this.iconDescriptions[i] });
    this.colourLegend.appendChild(legendEntry);

  }

  this.askapMap.controls[google.maps.ControlPosition.TOP_RIGHT].push(
    this.colourLegend
  );
};

askapLivePage.prototype.googleMapShowDetails = function(antenna) {

  // fill the antenna status div sections
  var antNumber = 'Antenna ' + this.antennaInfo[antenna.antNum][0];
  dojo.attr(dojo.byId('antennaNumber'), 'innerHTML', antNumber);

  var antName = this.antennaInfo[antenna.antNum][5];
  dojo.attr(dojo.byId('antennaName'), 'innerHTML', antName);

  var antImage = dojo.create('img', {
    'src': this.stateInfo[antenna.antState][2],
    'title': this.stateInfo[antenna.antState][1]
  });
  dojo.empty(dojo.byId('antennaImage'));
  dojo.byId('antennaImage').appendChild(antImage);

  var antState = this.stateInfo[antenna.antState][0];
  dojo.attr(dojo.byId('antennaState'), 'innerHTML', antState);


  // make the currently selected icon smaller
  if (this.currentAntSelection != null) {
    this.currentAntSelection.setIcon(
      this.icons[this.currentAntSelection.colour].small);
    this.currentAntSelection.setShadow(this.icons.shadow.small);
    dojo.removeClass('antennaDetails', 'details' +
      this.currentAntSelection.colour);
    this.currentAntSelection = null;
  }

  // make the newly selected icon bigger
  antenna.setIcon(this.icons[antenna.colour].large);
  antenna.setShadow(this.icons.shadow.large);
  this.currentAntSelection = antenna;
  // colour the details div
  dojo.addClass('antennaDetails', 'details' + antenna.colour);

  // add some antenna navigation if we can
  var tNum = parseInt(this.antennaInfo[antenna.antNum][0]);
  if (tNum > this.minAntNumber && this.navigationPrev == null) {
    dojo.place('<span id="prevAnt">Previous</span>', 'antennaNavMinus',
      'only');
    this.navigationPrev = dojo.connect(dojo.byId('prevAnt'), 'onclick', this,
      this.googleMapAntPrevious);
  }
  if (tNum < this.maxAntNumber && this.navigationNext == null) {
    dojo.place('<span id="nextAnt">Next</span>', 'antennaNavPlus',
      'only');
    this.navigationNext = dojo.connect(dojo.byId('nextAnt'), 'onclick', this,
      this.googleMapAntNext);
  }
  if (tNum == this.minAntNumber && this.navigationPrev != null) {
    dojo.disconnect(this.navigationPrev);
    this.navigationPrev = null;
    dojo.empty(dojo.byId('antennaNavMinus'));
  }
  if (tNum == this.maxAntNumber && this.navigationNext != null) {
    dojo.disconnect(this.navigationNext);
    this.navigationNext = null;
    dojo.empty(dojo.byId('antennaNavPlus'));
  }
};

askapLivePage.prototype.googleMapAntNext = function() {
  // select the next antenna
  var nNum = parseInt(this.antennaInfo[this.currentAntSelection.antNum][0]) + 1;
  for (var i = 0; i < this.antennaInfo.length; i++) {
    var tNum = parseInt(this.antennaInfo[i][0]);
    if (tNum == nNum) {
      this.googleMapShowDetails(this.antennaInfo[i][8]);
      break;
    }
  }
};

askapLivePage.prototype.googleMapAntPrevious = function() {
  // select the next antenna
  var nNum = parseInt(this.antennaInfo[this.currentAntSelection.antNum][0]) - 1;
  for (var i = 0; i < this.antennaInfo.length; i++) {
    var tNum = parseInt(this.antennaInfo[i][0]);
    if (tNum == nNum) {
      this.googleMapShowDetails(this.antennaInfo[i][8]);
      break;
    }
  }
};

askapLivePage.prototype.googleMapAntColour = function(antennaStateNum) {

  // determine the colour of the icon we will give the antenna
  var antIconColour = 'white';
  if (antennaStateNum == 4) {
    // the antenna is being constructed
    antIconColour = 'cyan';
  } else if (antennaStateNum == 1 || antennaStateNum == 3) {
    // the antenna is pretty much complete
    antIconColour = 'green';
  } else if (antennaStateNum == 5 || antennaStateNum == 6 ||
	     antennaStateNum == 7 || antennaStateNum == 8) {
    // a BETA antenna
    antIconColour = 'gold';
  }

  return antIconColour;
};

askapLivePage.prototype.googleMapLoadIcons = function() {
  // load the antenna marker icons
  this.iconColours = ['white', 'cyan', 'green', 'gold'];
  this.iconDescriptions = [
    'Not yet being constructed',
    'Under construction',
    'Construction completed',
    'Part of BETA'
  ];
  this.icons = { };
  this.iconFiles = [];

  for (var i = 0; i < this.iconColours.length; i++) {
    var iconName = 'askap_icon_' + this.iconColours[i] + '.png';
    this.iconFiles.push(iconName);
    this.icons[this.iconColours[i]] = {};
    this.icons[this.iconColours[i]].small =
      new google.maps.MarkerImage(iconName,
      new google.maps.Size(40, 48),
      new google.maps.Point(0, 0),
      new google.maps.Point(14, 48),
      new google.maps.Size(27, 32));
    this.icons[this.iconColours[i]].large =
      new google.maps.MarkerImage(iconName,
      new google.maps.Size(40, 48),
      new google.maps.Point(0, 0),
      new google.maps.Point(14, 48));
  }

  this.icons.shadow = {};
  this.icons.shadow.small =
    new google.maps.MarkerImage('askap_icon_shadow.png',
    new google.maps.Size(57, 30),
    new google.maps.Point(0, 0),
    new google.maps.Point(14, 30),
    new google.maps.Size(38, 20));
  this.icons.shadow.large =
    new google.maps.MarkerImage('askap_icon_shadow.png',
    new google.maps.Size(57, 30),
    new google.maps.Point(0, 0),
    new google.maps.Point(14, 30));

  // the active shape of the icon
  this.iconShape = {
      coord: [8, 48, 7, 33, 12, 27, 3, 17, 1, 7, 38, 0, 40, 37,
	      26, 36, 19, 32, 20, 48],
      type: 'poly'
  };

};

askapLivePage.prototype.getPageText = function() {
  this.dbQuery({
    content: {
      action: 'wiki_content'
    },
    functionCall: 'showText'
  });
};

askapLivePage.prototype.showText = function(data, ioargs) {
  // make the WikiCreole area
  this.creole = new Parse.Simple.Creole({ forIE: document.all });
  this.wikiText = data;

  this.renderText();
};

askapLivePage.prototype.renderText = function() {
  dojo.empty(dojo.byId('text_content'));
  this.creole.parse(dojo.byId('text_content'), this.wikiText);
};

askapLivePage.prototype.dbQuery = function(options) {
  dojo.xhrPost({
    url: '/cgi-bin/obstools/askap_live/dbinterface.pl',
    sync: false,
    content: options.content,
    load: dojo.hitch(this, options.functionCall),
    error: function(error, ioargs) {
      alert(error);
    }
  });
};

function init(){

  // make a new ASKAP Live Page instance
  var askapLive = new askapLivePage();

}

dojo.addOnLoad(init);
